#include <linux/tty.h>

unsigned long video_num_columns;      // 显示列数
unsigned long video_num_lines;        // 显示行数

static unsigned char video_type;      // 显示模式
static unsigned long video_mem_base;  // 显存起始地址
static unsigned long video_mem_term;  // 显存结束地址
static unsigned long video_size_row;  // 每行字节数
static unsigned char video_page;      // 初始页面
static unsigned short video_port_reg; // 显示控制器索引寄存器端口
static unsigned short video_port_val; // 显示控制器数据寄存器端口
static int can_do_color = 0;          // 是否可以彩色显示

static struct {
    unsigned char vc_attr;            // 当前字符的属性（颜色，亮度等）
    unsigned long vc_origin;          // 用于EGA/VGA快速滚动
    unsigned long vc_pos;             // 当前字符位置
    unsigned long vc_x, vc_y;         // 光标所在位置
    unsigned long vc_video_mem_start; // 视频RAM开始地址
    unsigned long vc_video_mem_end;   // 视频RAM结束地址
} vc_cons;

#define origin          (vc_cons.vc_origin)
#define pos             (vc_cons.vc_pos)
#define x               (vc_cons.vc_x)
#define y               (vc_cons.vc_y)
#define attr            (vc_cons.vc_attr)
#define video_mem_start (vc_cons.vc_video_mem_start)
#define video_mem_end   (vc_cons.vc_video_mem_end)

static void gotoxy(int new_x, int new_y) {
    int max_y;

    if (new_x < 0)
        x = 0;
    else if (new_x >= video_num_columns)
        x = video_num_columns - 1;
    else
        x = new_x;
    max_y = video_num_lines;
    if (new_y < 0)
        y = 0;
    else if (new_y >= max_y)
        y = max_y - 1;
    else
        y = new_y;
    pos = origin + y * video_size_row + (x << 1);
}

void console_print(const char *b) {
    unsigned char c;

    while ((c = *(b++)) != 0) {
        *(unsigned short *)pos = (attr << 8) + c;
        x++;
        pos += 2;
    }
}

void con_init() {
    char *display_desc = "????";
    char *display_ptr;
    int orig_x = ORIG_X;
    int orig_y = ORIG_Y;

    video_num_columns = ORIG_VIDEO_COLS;    // 列数
    video_size_row = video_num_columns * 2; // 每行字符数
    video_num_lines = ORIG_VIDEO_LINES;     // 行数
    video_page = ORIG_VIDEO_PAGE;           // 页号

    if (ORIG_VIDEO_MODE == 7) {             // 单色显示
        video_mem_base = 0xb0000;
        video_port_reg = 0x3b4;
        video_port_val = 0x3b5;
        if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
            video_type = VIDEO_TYPE_EGAM;
            video_mem_term = 0xb8000;
            display_desc = "EGA+";
        } else {
            video_type = VIDEO_TYPE_MDA;
            video_mem_term = 0xb2000;
            display_desc = "*MDA";
        }
    } else { // 彩色显示
        can_do_color = 1;
        video_mem_base = 0xb8000;
        video_port_reg = 0x3d4;
        video_port_val = 0x3d5;
        if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
            video_type = VIDEO_TYPE_EGAC;
            video_mem_term = 0xc0000;
            display_desc = "EGA+";
        } else {
            video_type = VIDEO_TYPE_CGA;
            video_mem_term = 0xba000;
            display_desc = "*CGA";
        }
    }

    attr = 0x07;

    video_mem_start = video_mem_base;
    video_mem_end = video_mem_term;
    origin = video_mem_start;

    gotoxy(orig_x, orig_y);

    // 打印正在使用的显示驱动程序
    display_ptr = ((char *)video_mem_base) + video_size_row - 8;
    while (*display_desc) {
        *display_ptr++ = *display_desc++;
        display_ptr++;
    }
}
